package com.elite.groovy.callback

import com.alibaba.fastjson.JSONObject
import com.elite.groovy.kh.ChatResult
import com.elite.groovy.kh.KHDBConfig
import com.elite.groovy.kh.KHUtil
import com.elite.groovy.util.Util
import com.elite.groovy.util.EliteBean
import com.elite.groovy.util.IpAddressUtil
import org.apache.commons.logging.Log
import org.apache.commons.logging.LogFactory
import org.springframework.jdbc.core.JdbcTemplate

import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

/**
 * @projectName: Groovy
 * @package: com.elite.groovy.callback
 * @className: apiChatClientLogin
 * @description: 网聊登录用户身份鉴权及队列识别
 * @author: LiJT
 * @date: 2023-10-27 11:13
 * @version: 1.0
 */

public class apiChatClientLogin implements ServiceBackInvoke {
    private static final Log log = LogFactory.getLog(apiChatClientLogin.class);
    private static StringBuffer to_Queue_Info = new StringBuffer();
    private static String in_DOMAIN = "";

    public String doCallBack(EliteBean eliteBean, HttpServletRequest request, HttpServletResponse response) {

        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json;charset=UTF-8");
        long startTime = System.currentTimeMillis();
        String outData = "";

        // 清空进线队列规则日志
        to_Queue_Info.setLength(0);

        // 调用IP过滤
        if (KHDBConfig.getParam(eliteBean, "#APIIP") == "1" && !KHUtil.getRemoteHost(request)) {
            outData = "API被非法IP调用-Request Not Allow!" + IpAddressUtil.getIpAddress(request);
            log.warn(outData);
            return JSONObject.toJSONString(new ChatResult(ChatResult.ERROR, false, outData));
        }

        String getMethod = request.getMethod();
        log.debug("HTTP请求调用类型 getMethod:" + getMethod);
        if (getMethod != "POST") {
            outData = "HTTP请求调用类型错误，接口调用失败：" + getMethod;
            log.error(outData);
            return JSONObject.toJSONString(new ChatResult(ChatResult.ERROR, false, outData));
        }

        // 获取所有Header
        Map<String, String> mapHeader = new HashMap<String, String>();
        Enumeration headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String key = (String) headerNames.nextElement();
            String value = request.getHeader(key);
            log.debug("Call Header-" + key + ":" + value);

            mapHeader.put(key, value);
        }

        // 获取所有参数名
        Map<String, String> mapParam = new HashMap<String, String>();
        Enumeration ep = request.getParameterNames();
        while (ep.hasMoreElements()) {
            String key = (String) ep.nextElement();
            String value = request.getParameter(key);
            log.debug("Call Parameter-" + key + ":" + value);
            mapParam.put(key, value);

        }


        //初始化本地参数
        in_DOMAIN = KHUtil.isNull(in_DOMAIN) ? KHDBConfig.getAPIURL(eliteBean, "SYS-InnerDomain") : in_DOMAIN;
        in_DOMAIN = in_DOMAIN.endsWith("/") ? in_DOMAIN : in_DOMAIN + "/";

        // 获取嵌入传递的参数
        String userId = mapParam.get("userId");
        // if(!(mapParam.get("brand").equals("4"))){
        //   userId = KHUtil.GetMapV(mapParam,"userId");
        // }
        if (KHUtil.isNull(userId)) {
            outData = "HTTP请求调用错误 userId：" + userId;
            log.error(outData);
            return JSONObject.toJSONString(new ChatResult(ChatResult.ERROR, false, outData));
        }

        // 获取数据源List<Map<String, Object>>
        JdbcTemplate jt = new JdbcTemplate(eliteBean.getDataSource());

        try {
            // 网聊客户请求参数
            String res_Brand = doChatLoginParams(jt, mapParam);

            // 客户信息处理
            JSONObject loginResult = doCustomerMain(jt, mapParam);

            // 队列信息处理
            int loginQueue = doQueueMain(jt, mapParam, loginResult);

            // 登录处理信息
            outData = JSONObject.toJSONString(new ChatResult(ChatResult.SUCCESS, true, outData, loginQueue, loginResult.getString("Customer_Guid"), res_Brand, loginResult));
            doChatLoginHis(jt, mapParam, loginResult.getString("Customer_Guid"), String.valueOf(loginQueue), outData, (System.currentTimeMillis() - startTime));

            // 记录队列识别结果
            String updateinparamsSQL = '''update dg_chat_inparams set to_queue_info = ? where rec_guid = ?''';
            jt.update(updateinparamsSQL, to_Queue_Info, res_Brand);

            log.debug("登录处理完成【返回结果】：" + outData + " 总耗时:" + (System.currentTimeMillis() - startTime).toString());

            return outData;

        } catch (Exception e) {
            outData = "HTTP请求调用错误，接口处理异常：" + e.getMessage();
            log.error(outData, e);
            return JSONObject.toJSONString(new ChatResult(ChatResult.ERROR, false, outData));

        }
    }

    // 客户进线Customer信息处理
    public static JSONObject doCustomerMain(JdbcTemplate jt, Map<String, String> mapParam) {

        // 初始化返回
        JSONObject resMap = new JSONObject();

        // 调用参数信息
        String com = mapParam.get("com");
        String id = mapParam.get("id");
        String userId = mapParam.get("userId");
        String userMobile = mapParam.get("userMobile");
        String userName = mapParam.get("userName");
        String region = mapParam.get("region");
        String province = mapParam.get("province");
        String city = mapParam.get("city");
        String salesterritory = mapParam.get("salesterritory");
        String sourcesys = mapParam.get("sourcesys");
        String channeltype = mapParam.get("channeltype");
        String ip = mapParam.get("ip");
        String organization = mapParam.get("organization");
        String finaorgid = mapParam.get("finaorgid");

        String querySQL = "Select Customer_Guid, Stringfield9, Stringfield11 From Customer Where 1 = 1 And Customer_Id = ? Limit 1";

        List<Map<String, Object>> querySQLR = jt.queryForList(querySQL, userId);

        // 初始化网聊登录信息
        String loginName = "";// 网聊登录ID
        String password = "";// 网聊登录密码

        if (querySQLR.size() > 0) {
            String re_Customer_Guid = querySQLR.get(0).get("Customer_Guid");// 客户主键Guid
            loginName = querySQLR.get(0).get("Stringfield9");// 网聊登录ID
            password = querySQLR.get(0).get("Stringfield11");// 网聊登录密码

            // 当客户记录存在时，更新客户信息
            String updateSQL = "UPDATE Customer SET " +
                    "Customername = ?, " +
                    "Mobile = ?, " +
                    "Province = ?, " +
                    "City = ?, " +
                    "Area = ?, " +
                    "Username = ?, " +
                    "Region = ?, " +
                    "Sourcesys = ?, " +
                    "Channeltype = ?, " +
                    "Organization = ?, " +
                    "Finaorgid = ?, " +
                    "Modifiedby = 'SECHAT', " +
                    "Modifieddate = Now() " +
                    "Where Customer_Guid = ?";

            int updateNum = jt.update(updateSQL,
                    userName,
                    userMobile,
                    province,
                    city,
                    salesterritory,
                    userName,
                    region,
                    sourcesys,
                    channeltype,
                    organization,
                    finaorgid,
                    re_Customer_Guid);

            log.debug("doCustomerMain 客户信息已更新，更新条数: " + updateNum + ", Customer_Guid: " + re_Customer_Guid);

            loginName = KHUtil.isNull(loginName) ? userId : loginName;
            password = KHUtil.isNull(password) ? "" : password;
            resMap.put("loginName", loginName);
            resMap.put("password", password);
            resMap.put("Customer_Guid", re_Customer_Guid);


        } else {
            log.debug(mapParam.get("brand"))
            if (!(mapParam.get("brand").equals("4"))) {
                //其他渠道
                log.debug('其他渠道')
                String re_Customer_Guid = "CHAT_" + KHUtil.getRandomString(31).toUpperCase();
                String insertCust = '''Insert Into Customer (Customer_Guid, Customer_Id, Customername, Mobile, Others, Createdby, Createddate, Modifiedby, Modifieddate, Stringfield9, Province, City, Area, Userid, Username, Region, Sourcesys, Channeltype, Organization, Finaorgid) Values (?, ?, ?, ?, ?, 'SECHAT', Now(), 'SECHAT', Now(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''';

                int ins_Num = jt.update(insertCust, re_Customer_Guid, userId, userName, userMobile, userMobile, userId, province, city, salesterritory, userId, userName, region, sourcesys, channeltype, organization, finaorgid);
                log.debug("doCustomerMain 进线客户-客户信息处理新增:" + ins_Num);

                resMap.put("loginName", userId);
                resMap.put("password", "");
                resMap.put("Customer_Guid", re_Customer_Guid);
            } else {
                //好工匠
                String APISql = '''select parametervalue from sysc_parameter where parameter_id = ?'''
                List APISqlRes = jt.queryForList(APISql, 'HGJAPI');
                if (APISqlRes.size() == 0) {
                    log.debug("API未配置");
                    return null;
                }
                def hgj_url = APISqlRes.get(0).get("parametervalue")
                Map<String, Object> headMap = new HashMap<>()
                headMap.put("authorization", "Bearer pHmqWtrn5bRVRbRwRHEPpCNhNPrCW1quOZBsFTmWwCk3RQfXkn0vZPYWzt9bbeMziy89AQ9qpn0KLtXRg4wmvvdbe2qS86ssBUAYemdv3V2vlv4ZJGUzRP0ZMm6a2tEV")
                String callRes = Util.doHttpGetUseHead(hgj_url + '/api/third/live/userinfo?userId=' + userId, "UTF-8", 5000, 0, headMap);
                def res = JSONObject.parseObject(callRes)
                log.debug("接口返回信息" + res);
                if (res.code == 200) {
                    def data = res.data
                    String re_Customer_Guid = "CHAT_HGJ" + KHUtil.getRandomString(28).toUpperCase();
                    def insertCust = """Insert Into Customer 
                                      (Customer_Guid, Customer_Id, Customername, Mobile, Createdby, Createddate, Modifiedby, Modifieddate, Stringfield9, Userid, Username,hgj_cust_info) Values 
                                      (?, ?, ?, ?, 'SECHAT', Now(), 'SECHAT', Now(), ?, ?, ?, ?)""";

                    userName = data.name;
                    int ins_Num = jt.update(insertCust, re_Customer_Guid, userId, userName, userId, userId, userId, userName, callRes);
                    log.debug("doCustomerMain 进线客户-客户信息处理新增:" + ins_Num);

                    resMap.put("loginName", userId);
                    resMap.put("password", "");
                    resMap.put("Customer_Guid", re_Customer_Guid);

                } else {
                    log.debug('好工匠接口异常')
                }
            }

        }
        log.debug("doCustomerMain [resMap]:" + resMap);
        return resMap;

    }

    // 客户进线队列识别
    public static int doQueueMain(JdbcTemplate jt, Map<String, String> mapParam, JSONObject loginResult) {
        // 初始化默认队列
        int robot_QueueId = 1; //机器人队列
        int ex_QueueId = 2; //专属队列

        // 好工匠小程序
        if (mapParam.get("brand").equals("4")) {
            return 4;
        }


        //获取客户信息
        String Customer_Guid = loginResult.get("Customer_Guid");

        if (KHUtil.isNull(Customer_Guid)) {
            // 客户不存在，默认队列
            log.debug("doQueueMain 未获取到Customer_Guid,机器人队列：" + robot_QueueId);
            return robot_QueueId;
        } else {
            // 调用参数信息
            String userId = mapParam.get("userId");
            log.debug("doQueueMain 获取人工队列入参:" + mapParam.toString());

            // 检查是否存在有效的SessionId，优先寻找专属
            String SessionSQL = '''select id, perm_flag from chat_session where client_id = ? and perm_flag = 1'''
            List SessionList = jt.queryForList(SessionSQL, Customer_Guid);
            String SessionID = "";
            if (SessionList.size() > 0) {
                SessionID = SessionList.get(0).get("id");
            }

            // 查询当前客户是否存在历史专属会话
            String ChatRouteSQL = '''select route_guid, ownerstaff_id from chat_multichannel_route where customer_guid = ?'''
            List<Map<String, Object>> ChatRouteList = jt.queryForList(ChatRouteSQL, Customer_Guid);
            String old_Staff_ID = "";
            String old_Route_Guid = KHUtil.getRandomString(36).toUpperCase();
            if (ChatRouteList.size() > 0) {
                old_Staff_ID = ChatRouteList.get(0).get("ownerstaff_id");
                old_Route_Guid = ChatRouteList.get(0).get("route_guid");
                logDebug("doQueueMain 查询当前客户是否存在历史专属会话 结果：" + old_Staff_ID);
            }

            // 检查当前客户是否匹配现有规则以及是否在线
            JSONObject doHumanQueueR = doHumanQueue(jt, Customer_Guid, userId, old_Staff_ID);
            logDebug("doQueueMain 检查当前客户是否匹配现有规则以及是否在线 结果：" + doHumanQueueR.toString());

            String new_Staff_ID = GetFSJV(doHumanQueueR, "res_staff_id");
            logDebug("doQueueMain 找到当前客户最新专属坐席：" + new_Staff_ID);

            // 找不到专属坐席时，直接转到机器人队列
            if (KHUtil.isNull(new_Staff_ID)) {
                return robot_QueueId;
            }

            if (!KHUtil.isNull(new_Staff_ID) && KHUtil.isNull(old_Staff_ID)) {
                // 如果找到专属坐席, 且无原专属坐席新增&更新路由表Replace具备存在更新不存在新建作用
                String updaterouteSQL = '''Replace into chat_multichannel_route
                                              (route_guid, customer_guid, ownerstaff_id, bind_status, lastupdateinfotime, operation_by, operation_status)
                                            values
                                              (?, ?, ?, 1, now(), ?, '0')''';
                int ins_Num1 = jt.update(updaterouteSQL, old_Route_Guid, Customer_Guid, new_Staff_ID, new_Staff_ID);
                logDebug("doQueueMain 专属坐席路由新增&更新 Route_Guid：" + old_Route_Guid + " Customer_Guid:" + Customer_Guid + " new_Staff_ID:" + new_Staff_ID + " 更新历史DB:" + ins_Num1);

                // 记录变更历史
                String InsertrouteHisSQL = '''insert into channel_history (guid_his, route_guid, oldstaff, newstaff, createdate, customer_guid) select uuid(), route_guid, ownerstaff_id, ?, now(), ? from chat_multichannel_route where customer_guid = ?''';
                int ins_Num1_his = jt.update(InsertrouteHisSQL, new_Staff_ID, Customer_Guid, Customer_Guid);
                logDebug("doQueueMain 原专属坐席新增&更新 变更历史：" + old_Staff_ID + ">>>>" + new_Staff_ID + " 变更历史DB:" + ins_Num1_his);

            } else if (!KHUtil.isNull(new_Staff_ID) && old_Staff_ID != new_Staff_ID) {
                // 如果找到专属坐席, 且原专属坐席与最新专属坐席不一致,更新路由表

                String updaterouteSQL = '''update chat_multichannel_route set ownerstaff_id = ?, lastupdateinfotime = now(), bind_status = 1 where route_guid = ?''';
                int ins_Num1 = jt.update(updaterouteSQL, new_Staff_ID, old_Route_Guid);
                logDebug("doQueueMain 专属坐席路由更新Route_Guid：" + old_Route_Guid + " Customer_Guid:" + Customer_Guid + " new_Staff_ID:" + new_Staff_ID + " 更新历史DB:" + ins_Num1);

                //记录变更历史
                String InsertrouteHisSQL = '''insert into channel_history (guid_his, route_guid, oldstaff, newstaff, createdate, customer_guid) select uuid(), route_guid, ownerstaff_id, ?, now(), ? from chat_multichannel_route where customer_guid = ?''';
                int ins_Num1_his = jt.update(InsertrouteHisSQL, new_Staff_ID, Customer_Guid, Customer_Guid);
                logDebug("doQueueMain 原专属坐席更新 变更历史：" + old_Staff_ID + ">>>>" + new_Staff_ID + " 变更历史DB:" + ins_Num1_his);

                // 如果当前客户存在历史会话,将新坐席更新到原专属会话
                if (!KHUtil.isNull(SessionID)) {
                    String updateSessionSQL = '''update chat_session set last_agent_id = ?, agent_id = ?, close_by = null, end_time = null, end_time_by_timestamp = null, perm_flag = 1 where id = ?''';
                    int ins_Num2 = jt.update(updateSessionSQL, new_Staff_ID, new_Staff_ID, SessionID);
                    logDebug("doQueueMain 如果当前客户存在历史会话,将新坐席更新到原专属会话[" + SessionID + "] 变更历史DB:" + ins_Num2);
                }

            }
            return ex_QueueId;

        }


    }

    // 根据已存在客户，匹配规则并查找在线的坐席
    public static JSONObject doHumanQueue(JdbcTemplate jt, String Customer_Guid, String userId, String Old_StaffID) {
        JSONObject result = new JSONObject();
        logDebug("doHumanQueue # 客户进线Customer_Guid:" + Customer_Guid + " userId:" + userId + " Old_StaffID:" + Old_StaffID);

        String Res_Type = "";
        String Res_StaffID = "";
        String User_Status = ""; //不在线："",在线：1,忙碌：4

        JSONObject res_RuleJson = new JSONObject();

        // 初始化网聊登录信息
        String queueName = "默认队列";// 网聊登录queueName
        String Rec_Guid = "";// 临时规则ID

        // 根据Customer_guid获取请求信息
        String request_ParamSQL = '''Select R2.Rec_Guid,
                                           R2.Sourcesys, -- 来源系统
                                           R2.Region, -- 大区
                                           R2.Organization, -- 销售组织
                                           R2.Salesterritory, -- 销售区域
                                           R2.Usermobile, -- 手机号码
                                           R2.userId, -- 客户编号
                                           R2.userName -- 客户名称
                                      From Dg_Chat_Inparams R2
                                     Where R2.userId = ? order by update_time desc limit 1''';

        List<Map<String, Object>> request_ParamList = jt.queryForList(request_ParamSQL, userId);
        log.debug("doHumanQueue 获取聊天请求对应的客户进线信息:" + request_ParamList.toString());

        // 调用参数信息
        if (request_ParamList.size() > 0) {
            Rec_Guid = request_ParamList.get(0).get("Rec_Guid");

            String sourcesys = request_ParamList.get(0).get("Sourcesys") // 来源系统
            String sales_org = request_ParamList.get(0).get("Organization"); // 销售组织
            String sales_area = request_ParamList.get(0).get("Salesterritory"); // 销售区域
            String userName = request_ParamList.get(0).get("userName"); // 客户名称
            String userMobile = request_ParamList.get(0).get("Usermobile"); // 手机号码

            String querySQL = "";
            List<Map<String, Object>> default_RuleList = new ArrayList<Map<String, Object>>(); // 记录精准匹配到的规则，防止找到最后都没有在线坐席
            List<Map<String, Object>> query_RuleList = new ArrayList<Map<String, Object>>();

            // 1.客户名称匹配
            if (!KHUtil.isNull(userName)) {
                querySQL = '''select d.rules_id,
                                   d.system_id,
                                   d.system_name,
                                   d.area_id,
                                   d.area_name,
                                   d.organ_id,
                                   d.organ_name,
                                   d.salesterritory_id,
                                   d.salesterritory_name,
                                   d.custno,
                                   d.custname,
                                   d.mobile,
                                   d.custtype,
                                   d.staffstr_id,
                                   d.staffstr
                              from dg_chat_incoming_rules d
                             where 1 = 1
                               and d.status = 1
                              
                               and d.custname = ?
                             order by d.modifydate desc limit 1''';

                query_RuleList = jt.queryForList(querySQL, userName);
                logDebug("doHumanQueue L1-获取人工队列规则(直接通过客户名称匹配):" + query_RuleList.toString());

            }

            // 1-如果通过姓名匹配规则&识别到坐席
            if (query_RuleList.size() > 0) {
                default_RuleList = new ArrayList<>(query_RuleList);
                res_RuleJson = dealHumanRule(jt, query_RuleList, Old_StaffID);
                if (res_RuleJson.getInteger("res_type") > 0) {
                    return res_RuleJson;
                } else {
                    query_RuleList.clear();
                }
            }

            // 2.客户手机号码匹配
            if (!KHUtil.isNull(userMobile)) {
                querySQL = '''select d.rules_id,
                                   d.system_id,
                                   d.system_name,
                                   d.area_id,
                                   d.area_name,
                                   d.organ_id,
                                   d.organ_name,
                                   d.salesterritory_id,
                                   d.salesterritory_name,
                                   d.custno,
                                   d.custname,
                                   d.mobile,
                                   d.custtype,
                                   d.staffstr_id,
                                   d.staffstr
                              from dg_chat_incoming_rules d
                             where 1 = 1
                               and d.status = 1
                               and d.mobile = ?
                             order by d.modifydate desc limit 1''';

                query_RuleList = jt.queryForList(querySQL, userMobile);
                logDebug("doHumanQueue L2-获取人工队列规则(直接通过手机号):" + query_RuleList.toString());
            }

            // 2-如果通过姓名匹配规则&识别到坐席
            if (query_RuleList.size() > 0) {

                // 如果默认规则为空将新查到数据重置为默认
                if (!(default_RuleList.size() > 0)) {
                    default_RuleList = new ArrayList<>(query_RuleList);
                }
                res_RuleJson = dealHumanRule(jt, query_RuleList, Old_StaffID);
                if (res_RuleJson.getInteger("res_type") > 0) {
                    return res_RuleJson;
                } else {
                    query_RuleList.clear();
                }
            }

            // 3.如果通过客户姓名/手机号找到规则就不再使用通用规则(来源系统/大区/销售组织)
            int rule_Level = 1;
            while (rule_Level <= 2) {

                String where_SQL = "";
                if (rule_Level.equals(1)) {
                    where_SQL = "and d.organ_name = ? and d.salesterritory_name = ?";
                } else if (rule_Level.equals(2)) {
                    where_SQL = "and d.organ_name = ? and (d.salesterritory_name is null or d.salesterritory_name = '' or '######' = ?)";
                }

                querySQL = '''select d.rules_id,
                                   d.system_id,
                                   d.system_name,
                                   d.area_id,
                                   d.area_name,
                                   d.organ_id,
                                   d.organ_name,
                                   d.salesterritory_id,
                                   d.salesterritory_name,
                                   d.custno,
                                   d.custname,
                                   d.mobile,
                                   d.custtype,
                                   d.staffstr_id,
                                   d.staffstr
                              from dg_chat_incoming_rules d
                             where 1 = 1
                               and d.status = 1
                               and (d.custname is null or d.custname = '')
                               and (d.mobile is null or d.mobile = '')
                               and d.system_id = ?
                               and (d.organ_name = ? or d.organ_name is null or d.organ_name = '')
                               and (d.salesterritory_name = ? or d.salesterritory_name is null or d.salesterritory_name = '')
                             ''' + where_SQL + '''
                             order by case
                                        when d.organ_name is not null and d.organ_name != '' and d.salesterritory_name is not null and
                                             d.salesterritory_name != '' then
                                         1
                                        when d.organ_name is not null and d.organ_name != '' then
                                         2
                                        else
                                         99
                                      end,
                                      d.modifydate limit 1''';
                log.debug("doHumanQueue L3-获取人工队列规则(通用规则(" + rule_Level + ")) SQL:" + querySQL)

                query_RuleList = jt.queryForList(querySQL, sourcesys, sales_org, sales_area, sales_org, sales_area);
                logDebug("doHumanQueue L3-获取人工队列规则(通用规则(" + rule_Level + ")):" + query_RuleList.toString());

                // 循环级别处理
                rule_Level++;

                // 3-如果通过通用规则匹配规则&识别到坐席
                if (query_RuleList.size() > 0) {

                    // 如果默认规则为空将新查到数据重置为默认
                    if (!(default_RuleList.size() > 0)) {
                        default_RuleList = new ArrayList<>(query_RuleList);
                    }
                    res_RuleJson = dealHumanRule(jt, query_RuleList, Old_StaffID);
                    if (res_RuleJson.getInteger("res_type") > 0) {
                        return res_RuleJson;
                    } else {
                        query_RuleList.clear();
                    }
                }

            }

            // 所有级别规则已经完成识别,如果此时res_type <= 0 说明前面未识别到坐席
            logDebug("doHumanQueue End所有级别规则已经完成识别:" + res_RuleJson.toString() + " default_RuleList:" + default_RuleList.toString());
            if (res_RuleJson.getInteger("res_type") <= 0) {
                // 所有规则都没有识别到坐席时,如果有原坐席分配给原坐席,如果没有则取相对精准规则中首位坐席
                if (!KHUtil.isNull(Old_StaffID)) {
                    result.put("res_type", 3);
                    result.put("res_staff_id", Old_StaffID);
                    result.put("res_user_status", "");
                    result.put("res_msg", "所有规则都没有识别到坐席时,1/2 如果有原坐席分配给原坐席");
                    logDebug("doHumanQueue 所有规则都没有识别到坐席时,如果有原坐席分配给原坐席:" + Old_StaffID);
                } else {
                    if ((default_RuleList.size() > 0)) {
                        try {
                            String def_Staff_IDs = default_RuleList.get(0).get("staffstr_id").toString();
                            String[] def_Staff_IDArr = def_Staff_IDs.split(",");
                            result.put("res_type", 4);
                            result.put("res_staff_id", def_Staff_IDArr[0]);
                            result.put("res_user_status", "");
                            result.put("res_msg", "所有规则都没有识别到坐席时,2/2 如果没有则取相对精准规则中首位坐席");
                            logDebug("doHumanQueue 所有规则都没有识别到坐席时,无原坐席则取相对精准规则[" + def_Staff_IDs + "]中首位坐席:" + def_Staff_IDArr[0]);
                        } catch (Exception e) {
                            String outData = "doHumanQueue 解析默认规则中首位坐席时出现异常：" + e.getMessage();
                            log.warn(outData, e);

                        }
                    }
                }

            }

            // 记录队列识别结果
            String updateinparamsSQL = '''update dg_chat_inparams set staff_id = ?, perm_flag = ?, user_status = ? where rec_guid = ?''';
            jt.update(updateinparamsSQL, GetFSJV(result, "res_staff_id"), KHUtil.isNull(GetFSJV(result, "res_staff_id")) ? 0 : 1, GetFSJV(result, "res_user_status"), Rec_Guid);

        } else {
            result.put("res_type", 0);
            result.put("res_staff_id", "");
            result.put("res_user_status", "");
            result.put("res_msg", "无历史客户请求，直接转入机器人！");

        }
        logDebug("doHumanQueue *获取人工队列结果:" + result.toString());

        return result;

    }

    // 获取规则在线人
    public static JSONObject dealHumanRule(JdbcTemplate jt, List<Map<String, Object>> resRule_List, String old_StaffID) {

        JSONObject res_HumanJson = new JSONObject();
        logDebug("dealHumanRule - 入参old_StaffID(原专属坐席):" + old_StaffID + " resRule_List(规则数据):" + resRule_List);

        String res_Type = "";
        String res_StaffID = "";
        String res_User_Status = "";

        String old_Staff_ID = "";
        String old_User_Status = "";
        boolean is_Exist = false; //原坐席是否存在规则在线坐席中, 默认不存在


        if (resRule_List.size() > 0) {

            // 获取规则中的坐席
            String staffStr_IDs = resRule_List.get(0).get("staffstr_id").toString();
            logDebug("dealHumanRule - 读取规则配置全部坐席ID：" + staffStr_IDs);

            // 查找规则内的坐席属于哪个专属队列并且在线
            String checkSQL = "Select q.Id As Queueid, Cca.Id As Staff_Id, User_Status As User_Status From Queue q Left Join Property_Value Qv On Qv.Property_Key = q.Id Left Join Agent_Queue Aq On Aq. Queue_Id = q.Id Left Join Chat_Cache_Agentbyidmap Cca On Cca.Id = Aq.Agent_Id Where Find_In_Set(Cca.Id, ?) And Property_Id = 1035 And Cca.User_Status > 0 And Qv.Value = 1 Order By Find_In_Set(Cca.Id, ?)";
            List<Map<String, Object>> checkSQL_List = jt.queryForList(checkSQL, staffStr_IDs, staffStr_IDs);
            logDebug("dealHumanRule - 检查规则配置全部坐席&对应队列是否在线(登录)-结果:" + checkSQL_List.toString());

            // 检查是否通过规则找到有在线坐席
            if (checkSQL_List.size() > 0) {

                // 检查1:遍历当前规则在线坐席数组查找原专属坐席是否存在规则内
                for (int i = 0; i < checkSQL_List.size(); i++) {
                    old_Staff_ID = checkSQL_List.get(i).get("Staff_Id").toString();
                    old_User_Status = checkSQL_List.get(i).get("User_Status").toString();
                    is_Exist = old_StaffID.equals(old_Staff_ID);
                    if (is_Exist) {
                        break; //检查到存在，跳出
                    }
                }

                if (!is_Exist) {

                    res_StaffID = checkSQL_List.get(0).get("Staff_Id").toString();
                    res_User_Status = checkSQL_List.get(0).get("User_Status").toString();

                    res_HumanJson.put("res_type", 1);
                    res_HumanJson.put("res_staff_id", res_StaffID);
                    res_HumanJson.put("res_user_status", res_User_Status);
                    res_HumanJson.put("res_msg", "原坐席不在在线坐席清单中，取规则中在线坐席第一个坐席");

                } else {

                    res_HumanJson.put("res_type", 2);
                    res_HumanJson.put("res_staff_id", old_Staff_ID);
                    res_HumanJson.put("res_user_status", old_User_Status);
                    res_HumanJson.put("res_msg", "原坐席在在线坐席清单中，默认优先给原来的坐席");

                }

            } else {
                res_HumanJson.put("res_type", -1);
                res_HumanJson.put("res_staff_id", "");
                res_HumanJson.put("res_user_status", "");
                res_HumanJson.put("res_msg", "规则中无在线坐席,放弃处理");
            }


        } else {
            res_HumanJson.put("res_type", -1);
            res_HumanJson.put("res_staff_id", "");
            res_HumanJson.put("res_user_status", "");
            res_HumanJson.put("res_msg", "规则中无数据,放弃处理");

        }
        logDebug("dealHumanRule - 获取人工队列结果:" + res_HumanJson.toString());
        return res_HumanJson;
    }

    // 记录网聊客户请求日志
    public static String doChatLoginHis(JdbcTemplate jt, Map<String, String> mapParam, String Customer_Guid, String Result_Queue, String Result_Json, Long Cost_Time) throws Exception {
        String userId = mapParam.get("userId");
        String userName = mapParam.get("userName");
        String userMobile = mapParam.get("userMobile");

        // CustomerGuid生成
        String Rec_Guid = "HIS_" + KHUtil.getRandomString(32).toUpperCase();
        String InsertSQL = '''Insert Into Chat_Client_Params
                                  (Rec_Guid,
                                   Userid,
                                   Username,
                                   Usermobile,
                                   Params_Json,
                                   Customer_Guid,
                                   Result_Queue,
                                   Result_Json,
                                   Cost_Time)
                                Values
                                  (?, ?, ?, ?, ?, ?, ?, ?, ?)''';

        int insertNum = jt.update(InsertSQL, Rec_Guid, userId, userName, userMobile, getQueryString(mapParam, false), Customer_Guid, Result_Queue, Result_Json, Cost_Time);
        log.debug("记录网聊入参信息-【insertNum】:" + insertNum + " 【Customer_Guid】:" + Customer_Guid);

    }

    // 记录网聊客户请求参数
    public static String doChatLoginParams(JdbcTemplate jt, Map<String, String> mapParam) throws Exception {
        // 初始化返回
        String res_Brand = ""
        if (mapParam.get('brand').equals("4")) {
            res_Brand = "CPARS_HGJ" + KHUtil.getRandomString(26);
        } else {
            res_Brand = "CPARS_" + KHUtil.getRandomString(29);
        }

        // 调用参数信息
        String Device = mapParam.get("device");
        String Com = mapParam.get("com");
        String Id = mapParam.get("id");
        String Userid = mapParam.get("userId");
        String Usermobile = mapParam.get("userMobile");
        String Username = mapParam.get("userName");
        String Region = mapParam.get("region");
        String Province = mapParam.get("province");
        String City = mapParam.get("city");
        String Salesterritory = mapParam.get("salesterritory");
        String Sourcesys = mapParam.get("sourcesys");
        String Channeltype = mapParam.get("channeltype");
        String Ip = mapParam.get("ip");
        String Organization = mapParam.get("organization");
        String Finaorgid = mapParam.get("finaorgid");

        // 检查客户距离上一次进入时间是否有超过10分钟
        String InparamsSQL = '''select rec_guid from Dg_Chat_Inparams where Userid = ? and  update_time>now()- INTERVAL 10 MINUTE and PERM_FLAG=1 and ifnull(staff_id,'')!='' '''
        List<Map<String, Object>> InparamsSQLR = jt.queryForList(InparamsSQL, Userid);
        if (InparamsSQLR.size() > 0) {
            res_Brand = InparamsSQLR.get(0).get("rec_guid");
            String update_SQL = '''update dg_chat_inparams set update_time = now() where rec_guid = ?'''
            jt.update(update_SQL, res_Brand);
            log.debug("上次未超过10分钟的Dg_Chat_Inparams.rec_guid" + ":" + res_Brand);
        } else {

            log.debug("上次无超过10分钟的Dg_Chat_Inparams.rec_guid");

            // Chat_网聊客制化进线参数
            String InsertSQL = '''insert into dg_chat_inparams
                                      (rec_guid,
                                       device,
                                       com,
                                       id,
                                       userid,
                                       username,
                                       usermobile,
                                       sourcesys,
                                       channeltype,
                                       province,
                                       city,
                                       finaorgid,
                                       region,
                                       organization,
                                       salesterritory,
                                       ip,
                                       status,
                                       update_by,
                                       update_time,
                                       create_time)
                                    values
                                      (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, 'SELITE', now(), now())''';

            int insertNum = jt.update(InsertSQL, res_Brand, Device, Com, Id, Userid, Username, Usermobile, Sourcesys, Channeltype, Province, City, Finaorgid, Region, Organization, Salesterritory, Ip);
            log.debug("记录Chat_网聊客制化进线参数信息-【insertNum】:" + insertNum + " 【res_Brand】:" + res_Brand);

        }

        return res_Brand;

    }

    // 工具方法
    public static String getQueryString(Map<String, String> params, boolean is_encode) {
        String url = "";
        if (params == null) {
            return url;
        }

        StringBuilder builder = new StringBuilder(url);

        int i = 0;
        for (String key : params.keySet()) {
            String value = params.get(key);
            if (value == null) { // 过滤空的key
                continue;
            }

            if (i != 0) {
                builder.append('&');
            }

            builder.append(key);
            builder.append('=');

            if (is_encode) {
                builder.append(encode(value));
            } else {
                builder.append(value);
            }

            i++;
        }

        return builder.toString();
    }

    // 工具方法
    public static String encode(String input) {
        if (input == null) {
            return "";
        }

        try {
            return URLEncoder.encode(input, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return input;
    }

    // 解析Json值(此方法增加需要解析的key不存在保护)
    public static String GetFSJV(JSONObject inJson, String getKey) {
        String Rev_Value = null;
        try {
            Rev_Value = inJson.getString(getKey);
        } catch (Exception e) {
            try {
                Rev_Value = String.valueOf(inJson.getLong(getKey));
            } catch (Exception e1) {
                try {
                    Rev_Value = String.valueOf(inJson.getInteger(getKey));
                } catch (Exception e2) {
                    try {
                        Rev_Value = String.valueOf(inJson.getJSONArray(getKey));
                    } catch (Exception e3) {
                        try {
                            Rev_Value = String.valueOf(inJson.getJSONObject(getKey));
                        } catch (Exception e4) {
                            Rev_Value = "";
                        }
                    }
                }
            }
        } finally {
            if (Rev_Value == null || Rev_Value.equals("null") || Rev_Value.length() <= 0) {
                Rev_Value = "";
            }
        }
        return Rev_Value;
    }

    // 解析Json值(此方法增加需要解析的key不存在保护)
    public static void logDebug(String log_Info) {
        log.debug(log_Info);
        to_Queue_Info.append(System.lineSeparator() + log_Info);
    }

}